package org.jeecg.chase.common.supper.scene;

import org.apache.commons.lang3.StringUtils;
import org.jeecg.chase.common.base.annotation.Scene;
import org.jeecg.chase.common.utils.InvokeSupportUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author leikai
 * @version 1.0
 * @description:
 * @date 2021/07/23/0023 16:28
 */
public class SceneContainer {

    /**
     * 维护scene和class的键值对
     */
    private static Map<String, Class<?>> sceneClassMap = new HashMap<String, Class<?>>();

    public static void processSceneClass(Class<?> clazz) {
        List<String> sceneList = getScene(clazz);
        for (String scene : sceneList) {
            scene = scene.trim();
            set(scene, clazz);
        }
    }

    /**
     * 获取scene对应的class
     *
     * @param scene
     * @return java.lang.Class<?>
     * @author leikai
     * @date 2021/07/26/0026 16:36
     */
    public static Class<?> get(String scene) {
        Class<?> clazz = sceneClassMap.get(scene);
        if (null == clazz) {
            throw new RuntimeException("没有找到场景[" + scene + "]对应的class");
        }
        return clazz;
    }

    /**
     * 根据scene刷新class
     *
     * @param scene
     * @param clazz
     * @return void
     * @author leikai
     * @date 2021/07/26/0026 16:36
     */
    public static void set(String scene, Class<?> clazz) {
        sceneClassMap.put(scene, clazz);
    }

    /**
     * 根据class获取scene
     *
     * @param clazz
     * @return java.util.List<java.lang.String>
     * @author leikai
     * @date 2021/07/26/0026 16:44
     */
    private static List<String> getScene(Class<?> clazz) {
        List<String> sceneList = new ArrayList<String>();
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (isAnnotationedByScene(annotation)) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                Method method = null;
                try {
                    method = InvokeSupportUtils.getMethod(annotationType, "scene");
                } catch (Exception e) {
                    throw new RuntimeException(annotationType.getSimpleName() + "被@Scene注解，必须包含scene变量");
                }
                String scene = (String) InvokeSupportUtils.invokMethod(method, annotation);
                if (StringUtils.isNotBlank(scene)) {
                    sceneList.add(scene);
                }
            }
        }
        return sceneList;
    }

    /**
     * 判定annotation是否被Scene注解
     *
     * @param annotation
     * @return java.lang.Boolean
     * @author leikai
     * @date 2021/07/26/0026 16:45
     */
    private static Boolean isAnnotationedByScene(Annotation annotation) {
        Class<?> annotationType = annotation.annotationType();
        Annotation[] aannotations = annotationType.getAnnotations();
        for (Annotation aannotation : aannotations) {
            if (aannotation.annotationType().equals(Scene.class)) {
                return true;
            }
        }
        return false;
    }
}
